home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 17 / CU Amiga Magazine's Super CD-ROM 17 (1997)(EMAP Images)(GB)[!][issue 1997-12].iso / CUCD / Programming / DiceSource / src / fsovl / compress.c next >
C/C++ Source or Header  |  1997-09-09  |  20KB  |  859 lines

  1. /*
  2.  *    (c)Copyright 1992-1997 Obvious Implementations Corp.  Redistribution and
  3.  *    use is allowed under the terms of the DICE-LICENSE FILE,
  4.  *    DICE-LICENSE.TXT.
  5.  */
  6.  
  7. /*
  8.  * COMPRESS.C
  9.  */
  10.  
  11. #include "defs.h"
  12.  
  13. #define BITS  14    /* compression size */
  14.  
  15. Prototype void Compress(BPTR fh, char *buf, long bytes);
  16. Prototype void DeCompress(BPTR fh, char *buf, long bytes);
  17.  
  18. int initcomp(short bits);
  19. int compress(void);
  20. int decompress(void);
  21. void deletecomp(void);
  22. short comp_in(void);
  23. short decomp_in(void);
  24.  
  25. static long ErrorCode;
  26. static long Fh;
  27. static ubyte *MemBuf;
  28. static long  MemBytes;
  29.  
  30. static ubyte Buf[4096];
  31. static long BufIdx;
  32. static long BufLen;
  33.  
  34.  
  35. /*    WritePacket(fh, buf, bytes); */
  36. /*    ReadPacket(fh, buf, bytes);  */
  37.  
  38. void 
  39. Compress(BPTR fh, char *buf, long bytes)
  40. {
  41.     MemBytes = bytes;
  42.     MemBuf = buf;
  43.     BufIdx = 0;
  44.     BufLen = 0;
  45.     ErrorCode = 0;
  46.     Fh = fh;
  47.     if (initcomp(BITS) >= 0) {
  48.     compress();
  49.     WritePacket(fh, Buf, BufIdx);
  50.     }
  51.     deletecomp();
  52. }
  53.  
  54. void 
  55. DeCompress(BPTR fh, char *buf, long bytes)
  56. {
  57.     MemBytes = bytes;
  58.     MemBuf = buf;
  59.     Fh = fh;
  60.     BufIdx = 0;
  61.     BufLen = 0;
  62.     ErrorCode = 0;
  63.     if (initcomp(0) >= 0) {
  64.     decompress();
  65.     }
  66.     deletecomp();
  67. }
  68.  
  69. void
  70. comp_out(ubyte c)
  71. {
  72.     if (BufIdx == sizeof(Buf)) {
  73.     WritePacket(Fh, Buf, sizeof(Buf));
  74.     BufIdx = 0;
  75.     }
  76.     Buf[BufIdx++] = c;
  77. }
  78.  
  79. void
  80. comp_outn(ubyte *buf, long n)
  81. {
  82.     while (n) {
  83.     long r;
  84.  
  85.     if ((r = sizeof(Buf) - BufIdx) == 0) {
  86.         WritePacket(Fh, Buf, sizeof(Buf));
  87.         BufIdx = 0;
  88.         r = sizeof(Buf);
  89.     }
  90.     if (n < r)
  91.         r = n;
  92.     movmem(buf, Buf + BufIdx, r);
  93.     buf += r;
  94.     n -= r;
  95.     BufIdx += r;
  96.     }
  97. }
  98.  
  99. short
  100. comp_in()
  101. {
  102.     if (MemBytes) {
  103.     --MemBytes;
  104.     return(*MemBuf++);
  105.     }
  106.     return(EOF);
  107. }
  108.  
  109. short
  110. decomp_in()
  111. {
  112.     if (BufIdx == BufLen) {
  113.     BufIdx = 0;
  114.     BufLen = ReadPacket(Fh, Buf, sizeof(Buf));
  115.     if (BufLen == 0)
  116.         return(EOF);
  117.     }
  118.     return(Buf[BufIdx++]);
  119. }
  120.  
  121. long
  122. decomp_inn(ubyte *buf, long n)
  123. {
  124.     long ttl = 0;
  125.  
  126.     while (n) {
  127.     long r = BufLen - BufIdx;
  128.  
  129.     if (r == 0) {
  130.         BufIdx = 0;
  131.         BufLen = ReadPacket(Fh, Buf, sizeof(Buf));
  132.         if (BufLen == 0)
  133.         break;
  134.         r = BufLen;
  135.     }
  136.     if (n < r)
  137.         r = n;
  138.     movmem(Buf + BufIdx, buf, r);
  139.     buf += r;
  140.     n -= r;
  141.     BufIdx += r;
  142.     ttl += r;
  143.     }
  144.     return(ttl);
  145. }
  146.  
  147. void
  148. decomp_out(ubyte c)
  149. {
  150.     if (MemBytes) {
  151.     *MemBuf++ = c;
  152.     --MemBytes;
  153.     }
  154. }
  155.  
  156. /*
  157.  *  NOTE NOTE NOTE This file is included by uucp:src/lib/comp.c to
  158.  *  provide compression code, do not delete!
  159.  */
  160.  
  161. /*
  162.  * Copyright (c) 1985, 1986 The Regents of the University of California.
  163.  * All rights reserved.
  164.  *
  165.  * This code is derived from software contributed to Berkeley by
  166.  * James A. Woods, derived from original work by Spencer Thomas
  167.  * and Joseph Orost.
  168.  *
  169.  * Redistribution and use in source and binary forms are permitted
  170.  * provided that: (1) source distributions retain this entire copyright
  171.  * notice and comment, and (2) distributions including binaries display
  172.  * the following acknowledgement:  ``This product includes software
  173.  * developed by the University of California, Berkeley and its contributors''
  174.  * in the documentation or other materials provided with the distribution
  175.  * and in all advertising materials mentioning features or use of this
  176.  * software. Neither the name of the University nor the names of its
  177.  * contributors may be used to endorse or promote products derived
  178.  * from this software without specific prior written permission.
  179.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  180.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  181.  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  182.  *
  183.  * NOTE!!!!!!!!! This file is #include'd by src/lib/[un]comp.c
  184.  */
  185.  
  186.  
  187. #ifndef lint
  188. static char copyright[] =
  189. "@(#) Copyright (c) 1985, 1986 The Regents of the University of California.\n\
  190.  All rights reserved.\n";
  191. #endif /* not lint */
  192.  
  193. #ifndef lint
  194. static char sccsid[] = "@(#)compress.c  5.12 (Berkeley) 6/1/90";
  195. #endif /* not lint */
  196.  
  197. void error_decompress();
  198. void error_compress();
  199.  
  200. /*
  201.  * Compress - data compression program
  202.  */
  203. #define min(a,b)        ((a>b) ? b : a)
  204.  
  205. /*
  206.  * a code_int must be able to hold 2**BITS values of type int, and also -1
  207.  */
  208.  
  209. #if BITS > 15
  210. typedef long int    code_int;
  211. #else
  212. typedef int        code_int;
  213. #endif
  214.  
  215. typedef long int      count_int;
  216.  
  217. typedef    unsigned char    char_type;
  218. static char_type magic_header[] = { "\037\235" };      /* 1F 9D */
  219.  
  220. /* Defines for third byte of header */
  221. #define BIT_MASK    0x1f
  222. #define BLOCK_MASK    0x80
  223. /* Masks 0x40 and 0x20 are free.  I think 0x20 should mean that there is
  224.    a fourth header byte (for expansion).
  225. */
  226. #define INIT_BITS 9            /* initial number of bits/code */
  227.  
  228. /*
  229.  * compress.c - File compression ala IEEE Computer, June 1984.
  230.  *
  231.  * Authors:    Spencer W. Thomas    (decvax!utah-cs!thomas)
  232.  *        Jim McKie        (decvax!mcvax!jim)
  233.  *        Steve Davies        (decvax!vax135!petsd!peora!srd)
  234.  *        Ken Turkowski        (decvax!decwrl!turtlevax!ken)
  235.  *        James A. Woods        (decvax!ihnp4!ames!jaw)
  236.  *        Joe Orost        (decvax!vax135!petsd!joe)
  237.  *
  238.  */
  239.  
  240. void cl_hash(count_int);
  241. void cl_block(void);
  242. void output(code_int);
  243. code_int getcode(void);
  244.  
  245.  
  246.  
  247. #define ARGVAL() (*++(*argv) || (--argc && *++argv))
  248.  
  249. static int n_bits;        /* number of bits/code */
  250. static int maxbits;        /* user settable max # bits/code */
  251. static code_int maxcode;    /* maximum code, given n_bits */
  252. static code_int maxmaxcode;     /* should NEVER generate this code */
  253.  
  254. #define MAXCODE(n_bits)        ((1 << (n_bits)) - 1)
  255.  
  256. static count_int *htab[9];
  257. static unsigned short *codetab[5];
  258.  
  259. #define htabof(i)       (htab[(i) >> 13][(i) & 0x1fff])
  260. #define codetabof(i)    (codetab[(i) >> 14][(i) & 0x3fff])
  261.  
  262. static code_int hsize;    /* for dynamic table sizing */
  263. static count_int fsize;
  264. static int gc_offset = 0, gc_size = 0;
  265.  
  266. /*
  267.  * To save much memory, we overlay the table used by compress() with those
  268.  * used by decompress().  The tab_prefix table is the same size and type
  269.  * as the codetab.  The tab_suffix table needs 2**BITS characters.  We
  270.  * get this from the beginning of htab.  The output stack uses the rest
  271.  * of htab, and contains characters.  There is plenty of room for any
  272.  * possible stack (stack used to be 8000 characters).
  273.  */
  274.  
  275. #define tab_prefixof(i)     codetabof(i)
  276. #define tab_suffixof(i)        ((char_type *)htab[(i)>>15])[(i) & 0x7fff]
  277.  
  278. /*
  279.  *  it looked wrong the way it was before, so de_stack is back to normal
  280.  */
  281.  
  282. static char_type de_stack[24000];
  283.  
  284. static code_int free_ent = 0;               /* first unused entry */
  285. static int exit_stat = 0;               /* per-file status */
  286. static int perm_stat = 0;               /* permanent status */
  287.  
  288. static int nomagic = 0;        /* Use a 3-byte magic number header, unless old file */
  289. static int zcat_flg = 0;       /* Write output on stdout, suppress messages */
  290. static int precious = 1;       /* Don't unlink output file on interrupt */
  291. static int quiet = 1;           /* don't tell me about compression */
  292.  
  293. /*
  294.  * block compression parameters -- after all codes are used up,
  295.  * and compression rate changes, start over.
  296.  */
  297. static int block_compress = BLOCK_MASK;
  298. static int clear_flg = 0;
  299. static long int ratio = 0;
  300. #define CHECK_GAP 10000 /* ratio check interval */
  301. static count_int checkpoint = CHECK_GAP;
  302. /*
  303.  * the next two codes should not be changed lightly, as they must not
  304.  * lie within the contiguous general code space.
  305.  */
  306. #define FIRST    257    /* first free entry */
  307. #define CLEAR    256    /* table clear output code */
  308.  
  309. static int force = 0;
  310. static char ofname [100];
  311. static int bgnd_flag;
  312.  
  313. static int do_decomp = 0;
  314.  
  315. static int offset;
  316. static long int in_count = 1;        /* length of input */
  317. static long int bytes_out;        /* length of compressed output */
  318. static long int out_count = 0;        /* # of codes output (for debugging) */
  319.  
  320.  
  321. /*
  322.  * compress stdin to stdout
  323.  *
  324.  * Algorithm:  use open addressing double hashing (no chaining) on the
  325.  * prefix code / next character combination.  We do a variant of Knuth's
  326.  * algorithm D (vol. 3, sec. 6.4) along with G. Knott's relatively-prime
  327.  * secondary probe.  Here, the modular division first probe is gives way
  328.  * to a faster exclusive-or manipulation.  Also do block compression with
  329.  * an adaptive reset, whereby the code table is cleared when the compression
  330.  * ratio decreases, but after the table fills.    The variable-length output
  331.  * codes are re-sized at this point, and a special CLEAR code is generated
  332.  * for the decompressor.  Late addition:  construct the table according to
  333.  * file size for noticeable speed improvement on small files.  Please direct
  334.  * questions about this implementation to ames!jaw.
  335.  */
  336.  
  337. int
  338. compress() {
  339.     register long fcode;
  340.     register code_int i = 0;
  341.     register int c;
  342.     register code_int ent;
  343.     register code_int disp;
  344.     register code_int hsize_reg;
  345.     register int hshift;
  346.  
  347.     if (nomagic == 0) {
  348.     comp_out(magic_header[0]); comp_out(magic_header[1]);
  349.     comp_out((char)(maxbits | block_compress));
  350.     }
  351.  
  352.     offset = 0;
  353.     bytes_out = 3;        /* includes 3-byte header mojo */
  354.     out_count = 0;
  355.     clear_flg = 0;
  356.     ratio = 0;
  357.     in_count = 1;
  358.     checkpoint = CHECK_GAP;
  359.     maxcode = MAXCODE(n_bits = INIT_BITS);
  360.     free_ent = ((block_compress) ? FIRST : 256 );
  361.  
  362.     ent = comp_in ();
  363.  
  364.     hshift = 0;
  365.     for ( fcode = (long) hsize;  fcode < 65536L; fcode *= 2L )
  366.     hshift++;
  367.     hshift = 8 - hshift;        /* set hash code range bound */
  368.  
  369.     hsize_reg = hsize;
  370.     cl_hash( (count_int) hsize_reg);            /* clear hash table */
  371.  
  372.     while ( (c = comp_in()) != EOF ) {
  373.     in_count++;
  374.     fcode = (long) (((long) c << maxbits) + ent);
  375.     i = ((c << hshift) ^ ent);      /* xor hashing */
  376.  
  377.     if ( htabof (i) == fcode ) {
  378.         ent = codetabof (i);
  379.         continue;
  380.     } else if ( (long)htabof (i) < 0 )      /* empty slot */
  381.         goto nomatch;
  382.     disp = hsize_reg - i;        /* secondary hash (after G. Knott) */
  383.     if ( i == 0 )
  384.         disp = 1;
  385. probe:
  386.     if ( (i -= disp) < 0 )
  387.         i += hsize_reg;
  388.  
  389.     if ( htabof (i) == fcode ) {
  390.         ent = codetabof (i);
  391.         continue;
  392.     }
  393.     if ( (long)htabof (i) > 0 )
  394.         goto probe;
  395. nomatch:
  396.     output ( (code_int) ent );
  397.     out_count++;
  398.     ent = c;
  399.     if ( free_ent < maxmaxcode ) {
  400.         codetabof (i) = free_ent++; /* code -> hashtable */
  401.         htabof (i) =  fcode;
  402.     }
  403.     else if ( (count_int)in_count >= checkpoint && block_compress )
  404.         cl_block ();
  405.     }
  406.     /*
  407.      * Put out the final code.
  408.      */
  409.     output( (code_int)ent );
  410.     out_count++;
  411.     output( (code_int)-1 );
  412.  
  413.     if(bytes_out > in_count)    /* exit(2) if no savings */
  414.     exit_stat = 2;
  415.     return(ErrorCode);
  416. }
  417.  
  418.  
  419. /*****************************************************************
  420.  * TAG( output )
  421.  *
  422.  * Output the given code.
  423.  * Inputs:
  424.  *    code:    A n_bits-bit integer.  If == -1, then EOF.  This assumes
  425.  *        that n_bits =< (long)wordsize - 1.
  426.  * Outputs:
  427.  *    Outputs code to the file.
  428.  * Assumptions:
  429.  *    Chars are 8 bits long.
  430.  * Algorithm:
  431.  *    Maintain a BITS character long buffer (so that 8 codes will
  432.  * fit in it exactly).    Use the VAX insv instruction to insert each
  433.  * code in turn.  When the buffer fills up empty it and start over.
  434.  */
  435.  
  436. static char buf[BITS];
  437.  
  438. #ifndef vax
  439. static char_type lmask[9] = {0xff, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00};
  440. static char_type rmask[9] = {0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, 0x7f, 0xff};
  441. #endif /* vax */
  442.  
  443. void
  444. output( code )
  445. code_int  code;
  446. {
  447.     /*
  448.      * On the VAX, it is important to have the register declarations
  449.      * in exactly the order given, or the asm will break.
  450.      */
  451.     register int r_off = offset, bits= n_bits;
  452.     register char * bp = buf;
  453.  
  454.     if ( code >= 0 ) {
  455. /*
  456.  * byte/bit numbering on the VAX is simulated by the following code
  457.  */
  458.     /*
  459.      * Get to the first byte.
  460.      */
  461.     bp += (r_off >> 3);
  462.     r_off &= 7;
  463.     /*
  464.      * Since code is always >= 8 bits, only need to mask the first
  465.      * hunk on the left.
  466.      */
  467.     *bp = (*bp & rmask[r_off]) | (code << r_off) & lmask[r_off];
  468.     bp++;
  469.     bits -= (8 - r_off);
  470.     code >>= 8 - r_off;
  471.     /* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */
  472.     if ( bits >= 8 ) {
  473.         *bp++ = code;
  474.         code >>= 8;
  475.         bits -= 8;
  476.     }
  477.     /* Last bits. */
  478.     if(bits)
  479.         *bp = code;
  480.  
  481.     offset += n_bits;
  482.     if ( offset == (n_bits << 3) ) {
  483.         bp = buf;
  484.         bits = n_bits;
  485.         bytes_out += bits;
  486.         do
  487.         comp_out(*bp++);
  488.         while(--bits);
  489.         offset = 0;
  490.     }
  491.  
  492.     /*
  493.      * If the next entry is going to be too big for the code size,
  494.      * then increase it, if possible.
  495.      */
  496.     if ( free_ent > maxcode || (clear_flg > 0))
  497.     {
  498.         /*
  499.          * Write the whole buffer, because the input side won't
  500.          * discover the size increase until after it has read it.
  501.          */
  502.         if ( offset > 0 ) {
  503.         comp_outn(buf, n_bits);
  504.         bytes_out += n_bits;
  505.         }
  506.         offset = 0;
  507.  
  508.         if ( clear_flg ) {
  509.         maxcode = MAXCODE (n_bits = INIT_BITS);
  510.         clear_flg = 0;
  511.         }
  512.         else {
  513.         n_bits++;
  514.         if ( n_bits == maxbits )
  515.             maxcode = maxmaxcode;
  516.         else
  517.             maxcode = MAXCODE(n_bits);
  518.         }
  519.     }
  520.     } else {
  521.     /*
  522.      * At EOF, write the rest of the buffer.
  523.      */
  524.     if ( offset > 0 )
  525.         comp_outn( buf, (offset + 7) / 8);
  526.     bytes_out += (offset + 7) / 8;
  527.     offset = 0;
  528.     }
  529. }
  530.  
  531. /*
  532.  * Decompress stdin to stdout.    This routine adapts to the codes in the
  533.  * file building the "string" table on-the-fly; requiring no table to
  534.  * be stored in the compressed file.  The tables used herein are shared
  535.  * with those of the compress() routine.  See the definitions above.
  536.  */
  537.  
  538. int
  539. decompress() {
  540.     register char_type *stackp;
  541.     register int finchar;
  542.     register code_int code, oldcode, incode;
  543.  
  544.     /*
  545.      * As above, initialize the first 256 entries in the table.
  546.      */
  547.     maxcode = MAXCODE(n_bits = INIT_BITS);
  548.     for ( code = 255; code >= 0; code-- ) {
  549.     tab_prefixof(code) = 0;
  550.     tab_suffixof(code) = (char_type)code;
  551.     }
  552.     free_ent = ((block_compress) ? FIRST : 256 );
  553.  
  554.     finchar = oldcode = getcode();
  555.     if(oldcode == -1)   /* EOF already? */
  556.     return(-1);             /* Get out of here */
  557.     decomp_out( (char)finchar );       /* first code must be 8 bits = char */
  558.     if (ErrorCode)
  559.     return(-1);
  560.     stackp = de_stack;
  561.  
  562.     while ( (code = getcode()) > -1 ) {
  563.  
  564.     if ( (code == CLEAR) && block_compress ) {
  565.         for ( code = 255; code >= 0; code-- )
  566.         tab_prefixof(code) = 0;
  567.         clear_flg = 1;
  568.         free_ent = FIRST - 1;
  569.         if ( (code = getcode ()) == -1 )    /* O, untimely death! */
  570.         break;
  571.     }
  572.     incode = code;
  573.     /*
  574.      * Special case for KwKwK string.
  575.      */
  576.     if ( code >= free_ent ) {
  577.         *stackp++ = finchar;
  578.         code = oldcode;
  579.     }
  580.  
  581.     /*
  582.      * Generate output characters in reverse order
  583.      */
  584.     while ( code >= 256 ) {
  585.         *stackp++ = tab_suffixof(code);
  586.         code = tab_prefixof(code);
  587.  
  588.         if (stackp == de_stack + sizeof(de_stack)) {
  589.         --stackp;
  590.         return(-1);
  591.         }
  592.     }
  593.     *stackp++ = finchar = tab_suffixof(code);
  594.  
  595.     /*
  596.      * And put them out in forward order
  597.      */
  598.     do
  599.         decomp_out ( *--stackp );
  600.     while ( stackp > de_stack );
  601.  
  602.     /*
  603.      * Generate the new entry.
  604.      */
  605.     if ( (code=free_ent) < maxmaxcode ) {
  606.         tab_prefixof(code) = (unsigned short)oldcode;
  607.         tab_suffixof(code) = finchar;
  608.         free_ent = code+1;
  609.     }
  610.     /*
  611.      * Remember previous code.
  612.      */
  613.     oldcode = incode;
  614.     }
  615.     return(ErrorCode);
  616. }
  617.  
  618. /*****************************************************************
  619.  * TAG( getcode )
  620.  *
  621.  * Read one code from the standard input.  If EOF, return -1.
  622.  * Inputs:
  623.  *    stdin
  624.  * Outputs:
  625.  *    code or -1 is returned.
  626.  */
  627.  
  628.  
  629. code_int
  630. getcode() {
  631.     /*
  632.      * On the VAX, it is important to have the register declarations
  633.      * in exactly the order given, or the asm will break.
  634.      */
  635.     register code_int code;
  636.     static char_type buf[BITS];
  637.     register int r_off, bits;
  638.     register char_type *bp = buf;
  639.  
  640.     if ( clear_flg > 0 || gc_offset >= gc_size || free_ent > maxcode ) {
  641.     /*
  642.      * If the next entry will be too big for the current code
  643.      * size, then we must increase the size.  This implies reading
  644.      * a new buffer full, too.
  645.      */
  646.     if ( free_ent > maxcode ) {
  647.         n_bits++;
  648.         if ( n_bits == maxbits )
  649.         maxcode = maxmaxcode;    /* won't get any bigger now */
  650.         else
  651.         maxcode = MAXCODE(n_bits);
  652.     }
  653.     if ( clear_flg > 0) {
  654.         maxcode = MAXCODE (n_bits = INIT_BITS);
  655.         clear_flg = 0;
  656.     }
  657.     gc_size = decomp_inn( buf, n_bits);
  658.     if ( gc_size <= 0 )
  659.         return -1;            /* end of file */
  660.     gc_offset = 0;
  661.     /* Round size down to integral number of codes */
  662.     gc_size = (gc_size << 3) - (n_bits - 1);
  663.     }
  664.     r_off = gc_offset;
  665.     bits = n_bits;
  666.     /*
  667.      * Get to the first byte.
  668.      */
  669.     bp += (r_off >> 3);
  670.     r_off &= 7;
  671.     /* Get first part (low order bits) */
  672.     code = (*bp++ >> r_off);
  673.     bits -= (8 - r_off);
  674.     r_off = 8 - r_off;        /* now, offset into code word */
  675.     /* Get any 8 bit parts in the middle (<=1 for up to 16 bits). */
  676.     if ( bits >= 8 ) {
  677.         code |= *bp++ << r_off;
  678.         r_off += 8;
  679.         bits -= 8;
  680.     }
  681.     /* high order bits. */
  682.     code |= (*bp & rmask[bits]) << r_off;
  683.     gc_offset += n_bits;
  684.     if (code >= maxmaxcode) {
  685.     return(-1);
  686.     }
  687.  
  688.     return code;
  689. }
  690.  
  691. void
  692. cl_block ()             /* table clear for block compress */
  693. {
  694.     register long int rat;
  695.  
  696.     checkpoint = in_count + CHECK_GAP;
  697.  
  698.     if(in_count > 0x007fffff) { /* shift will overflow */
  699.     rat = bytes_out >> 8;
  700.     if(rat == 0) {          /* Don't divide by zero */
  701.         rat = 0x7fffffff;
  702.     } else {
  703.         rat = in_count / rat;
  704.     }
  705.     } else {
  706.     rat = (in_count << 8) / bytes_out;      /* 8 fractional bits */
  707.     }
  708.     if ( rat > ratio ) {
  709.     ratio = rat;
  710.     } else {
  711.     ratio = 0;
  712.     cl_hash ( (count_int) hsize );
  713.     free_ent = FIRST;
  714.     clear_flg = 1;
  715.     output ( (code_int) CLEAR );
  716.     }
  717. }
  718.  
  719. void
  720. cl_hash(hsize)          /* reset code table */
  721.     count_int hsize;
  722. {
  723.     long j;
  724.     long k = hsize;
  725.     count_int *htab_p;
  726.     long i;
  727.     long m1 = -1;
  728.  
  729.     for(j=0; j<=8 && k>=0; j++,k-=8192) {
  730.     i = 8192;
  731.     if(k < 8192) {
  732.         i = k;
  733.     }
  734.     htab_p = &(htab[j][i]);
  735.     i -= 16;
  736.     if(i > 0) {
  737.     do {                /* might use Sys V memset(3) here */
  738.         *(htab_p-16) = m1;
  739.         *(htab_p-15) = m1;
  740.         *(htab_p-14) = m1;
  741.         *(htab_p-13) = m1;
  742.         *(htab_p-12) = m1;
  743.         *(htab_p-11) = m1;
  744.         *(htab_p-10) = m1;
  745.         *(htab_p-9) = m1;
  746.         *(htab_p-8) = m1;
  747.         *(htab_p-7) = m1;
  748.         *(htab_p-6) = m1;
  749.         *(htab_p-5) = m1;
  750.         *(htab_p-4) = m1;
  751.         *(htab_p-3) = m1;
  752.         *(htab_p-2) = m1;
  753.         *(htab_p-1) = m1;
  754.         htab_p -= 16;
  755.     } while ((i -= 16) >= 0);
  756.     }
  757.     }
  758.     for ( i += 16; i > 0; i-- )
  759.         *--htab_p = m1;
  760. }
  761.  
  762. /*
  763.  *  dynamic decompression tag
  764.  */
  765.  
  766. int
  767. initcomp(bits)
  768. short bits;
  769. {
  770.     if (bits == 0) {
  771.     if ((decomp_in()!=(magic_header[0] & 0xFF))
  772.     || (decomp_in()!=(magic_header[1] & 0xFF))) {
  773.         return(-1);
  774.     }
  775.     bits = decomp_in();  /* set -b from file */
  776.     }
  777.  
  778.     block_compress = bits & BLOCK_MASK;
  779.     bits &= BIT_MASK;
  780.     maxmaxcode = ((code_int)1) << bits;
  781.     maxbits = bits;
  782.  
  783.     /*
  784.      *    some of these might be redundant
  785.      */
  786.  
  787.     offset = clear_flg = ratio = 0;
  788.     gc_offset = gc_size = 0;
  789.     in_count = 1;
  790.     checkpoint = CHECK_GAP;
  791.     n_bits = INIT_BITS;
  792.     maxcode = MAXCODE(INIT_BITS);
  793.     free_ent = ((block_compress) ? FIRST : 256);
  794.  
  795.     /*
  796.      *    set hsize
  797.      */
  798.  
  799.     switch(bits) {
  800.     case 16:
  801.     hsize = 69001;
  802.     break;
  803.     case 15:
  804.     hsize = 35023;
  805.     break;
  806.     case 14:
  807.     hsize = 18013;
  808.     break;
  809.     case 13:
  810.     hsize = 9001;
  811.     break;
  812.     default:
  813.     hsize = 5003;        /*    note: de_stack still fits   */
  814.     break;
  815.     }
  816.     {
  817.     int i;
  818.     long n;
  819.  
  820.     for (i = 0, n = hsize; i < 9 && n > 0; ++i) {
  821.         long entries = (n > 8192) ? 8192 : n;
  822.  
  823.         if ((htab[i] = calloc(1, sizeof(count_int) * entries)) == NULL)
  824.         return(-1);
  825.         n -= entries;
  826.     }
  827.  
  828.     for (i = 0, n = hsize; i < 5 && n > 0; ++i) {
  829.         long entries = (n > 16384) ? 16384 : n;
  830.  
  831.         if ((codetab[i] = calloc(1, sizeof(short) * entries)) == NULL)
  832.         return(-1);
  833.         n -= entries;
  834.     }
  835.     }
  836.     return(0);
  837. }
  838.  
  839. void
  840. deletecomp(void)
  841. {
  842.     int i;
  843.  
  844.     for (i = 0; i < sizeof(htab)/sizeof(htab[0]); ++i) {
  845.     if (htab[i]) {
  846.         free(htab[i]);
  847.         htab[i] = NULL;
  848.     }
  849.     }
  850.     for (i = 0; i < sizeof(codetab)/sizeof(codetab[0]); ++i) {
  851.     if (codetab[i]) {
  852.         free(codetab[i]);
  853.         codetab[i] = NULL;
  854.     }
  855.     }
  856. }
  857.  
  858.  
  859.